package com.suning.sawp.service.impl.model;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.google.common.base.Function;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.suning.api.rsf.service.ApiRemoteMapService;
import com.suning.framework.dal.client.DalClient;
import com.suning.rsf.consumer.ServiceLocator;
import com.suning.sawp.constants.ErrorCodeConstants;
import com.suning.sawp.dto.common.ReturnMsg;
import com.suning.sawp.dto.model.ModelInfo;
import com.suning.sawp.intf.model.ModelBindService;
import com.suning.sawp.intf.model.vo.BindResultInfo;
import com.suning.sawp.intf.model.vo.ModelBodyInfo;

@Service("modeBindService")
public class ModelBindServiceImpl implements ModelBindService {

    /**
     * 日志
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(ModelBindServiceImpl.class);

    private static final String SUCCESS = "T";

    private static final String BIND_FAIL = "R";

    private static final String BIND_FAIL_RETURN = "9001";

    ApiRemoteMapService queryProtoType = ServiceLocator.getService(ApiRemoteMapService.class,
            "scdps-pt-queryProtoTypeInfo");

    ApiRemoteMapService modifyProto = ServiceLocator.getService(ApiRemoteMapService.class,
            "scdps-pt-modifyProtoTypeBodyCode");

    /**
     * 数据库操作对象
     */
    @Resource
    DalClient dalClient;

    @Override
    public ModelBodyInfo queryModelInfoByCommcode(String commCode, String storeCode) {
        LOGGER.info("queryModelInfoByCommcode ,commCode:{},storeCode:{}", commCode, storeCode);
        ModelBodyInfo modelBodyInfo = new ModelBodyInfo();
        Map<String, Object> queryMap = new HashMap<String, Object>();
        queryMap.put("productCode", commCode);
        queryMap.put("storeCode", storeCode);
        Map<String, Object> result = queryProtoType.execute(queryMap);
        if (result == null) {
            LOGGER.error("queryModelInfoByCommcode error result is empty  ,commCode:{},storeCode:{}", commCode,
                    storeCode);
            return modelBodyInfo;
        }
        @SuppressWarnings("unchecked")
        List<Map<String, String>> dataList = (List<Map<String, String>>) result.get("dataList");

        List<ModelInfo> modelInfoList = Lists.newArrayList(Iterables.transform(dataList,
                new Function<Map<String, String>, ModelInfo>() {
                    @Override
                    public ModelInfo apply(Map<String, String> input) {
                        ModelInfo modelInfo = new ModelInfo();
                        modelInfo.setBodyCode(input.get("bodyCode"));
                        modelInfo.setCommCode(input.get("productCode"));
                        modelInfo.setCommName(input.get("productName"));
                        modelInfo.setDepotCode(input.get("depotCode"));
                        modelInfo.setInvQty(input.get("invQty"));
                        modelInfo.setLocationCode(input.get("locationCode"));
                        modelInfo.setSerialNo(input.get("serialNo"));
                        modelInfo.setStorageTime(input.get("storageTime"));
                        return modelInfo;
                    }
                }));

        modelBodyInfo.setModelInfoList(modelInfoList);
        if (CollectionUtils.isNotEmpty(modelInfoList)) {
            ModelInfo modelInfo = modelInfoList.get(0);
            modelBodyInfo.setCommName(modelInfo.getCommName());
            modelBodyInfo.setCommCode(commCode);
            modelBodyInfo.setSerialNoNum(String.valueOf(modelInfoList.size()));
        }
        return modelBodyInfo;
    }

    @SuppressWarnings("unchecked")
    @Override
    public ReturnMsg<BindResultInfo> bindModelBody(String serialNo, String bodyCode, String staffId, String commCode) {
        LOGGER.info("bindModelBody beg ,serialNo:" + serialNo + ",bodyCode  " + bodyCode + ",staffId  " + staffId
                + ",commCode  " + commCode);
        ReturnMsg<BindResultInfo> result = new ReturnMsg<BindResultInfo>();

        Map<String, Object> queryMap = new HashMap<String, Object>();
        queryMap.put("serialno", serialNo);
        queryMap.put("bodyCode", bodyCode);
        queryMap.put("staffId", staffId);
        queryMap.put("commCode", commCode);
        queryMap.put("updateTime", new Date());
        int insertResult = dalClient.execute("MODEL_BIND.SAVE_MODE_BIND", queryMap);

        if (insertResult > 0) {
            Map<String, Object> updateMap = new HashMap<String, Object>();
            updateMap.put("serialNo", serialNo);
            updateMap.put("bodyCode", bodyCode);
            updateMap.put("operator", staffId);
            Map<String, Object> updateReq = new HashMap<String, Object>();
            updateReq.put("dataList", Lists.newArrayList(updateMap));
            try {
                Map<String, Object> updateResult = modifyProto.execute(updateReq);
                if (updateResult != null && SUCCESS.equals(updateResult.get("resultFlag"))) {
                    LOGGER.info("bindModelBody end ,serialNo:" + serialNo + ",bodyCode  " + bodyCode + ",staffIfd  "
                            + staffId + ",commCode  " + commCode);
                    return result;
                } else if (updateResult != null && BIND_FAIL.equals(updateResult.get("resultFlag"))) {
                    LOGGER.info("bindModelBody bind fail end ,bindserialNo:" + serialNo + ",bindbodyCode  " + bodyCode
                            + ",staffIfd  " + staffId + ",commCode  " + commCode);
                    BindResultInfo bindResultInfo = new BindResultInfo();
                    bindResultInfo.setBodyCode(String.valueOf(updateResult.get("bodyCode")));
                    bindResultInfo.setSerialNo(String.valueOf(updateResult.get("serialNo")));
                    result.setData(bindResultInfo);
                    result.setError(BIND_FAIL_RETURN, "");
                } else {
                    LOGGER.error("bindModelBody fail end ,updateResult:" + updateResult);
                    result.setError(ErrorCodeConstants.ERR_0042);
                }
            } catch (Exception e) {
                LOGGER.error("bindModelBody exception  ,serialNo:" + serialNo + ",bodyCode  " + bodyCode
                        + ",staffIfd  " + staffId + ",commCode  " + commCode, e);
                result.setError(ErrorCodeConstants.ERR_0042);
            }
        } else {
            LOGGER.error("bindModelBody upodate fail   ,serialNo:" + serialNo + ",bodyCode  " + bodyCode
                    + ",staffIfd  " + staffId + ",insertResult  " + insertResult);
            result.setError(ErrorCodeConstants.ERR_0005);
        }
        return result;
    }
}
